阅读提示:TL;DR。文章包含大量源码,阅读时长较长,认真阅读可能超过20分钟。
回想一下,Spring最最核心的功能,终究是一个容器,用于提供所谓的”Bean
“,并负责Bean
之间的联结。而我们又知道,Bean
有不同的Scope
,即作用范围,单例的、原型的、Session
的,或自定义的。Bean
还能够懒加载。因此,创建Bean
的时机可能是运行时的任何时候。Spring使用BeanDefinition
描述一个Bean
的name、类、scope等元数据,并在需要时候创建。创建过程自然也包括了自动注入的过程。
本文我们重点关注Spring中对Bean
的管理。
如何描述Bean
Spring使用BeanDefinition
来描述Bean
,其继承拓扑图如上,我们只选取了几个具有代表性的来看。根绝BeanDefinition
接口的定义,能够知道,Spring中的Bean
具有如下特性:
基本信息
具有作用范围Scope
singleton:全局唯一实例
prototype:每次获取都创建新的实例
可以有父子关系
可以有依赖关系,即一个Bean的创建依赖于另一个Bean的存在
可延迟加载
可自动装配
设置是否参与自动装配(基于类型)
如果有多个类型符合要求,可设置主要的
可自定义Bean实例创建方式
设置工厂Bean,用另一个Bean来创建该Bean
设置工厂方法,用该方法创建实例
生命周期管理
可指定初始化方法 initMethod
可指定销毁方法 destroyMethod
具有角色,目前定义了三种角色,但暂未看到如何使用
ROLE_APPLICATION
:该Bean是应用的主体,默认值
ROLE_SUPPORT
:标识该Bean是其它更大部分的支持部分
ROLE_INFRASTRUCTURE
:该Bean作为纯基础设施的支持,用户接触不到它
获取构造方法的参数的值
获取MutablePropertyValues
,这对应的是Bean的属性键值对,自动注入时会使用。
BeanDefinition
可包装另一个BeanDefinition
,通过BeanDefinition getOriginatingBeanDefinition()
获取被包装的定义。
至于继承树中其它类,各自有所区别,我们依次看
AbstractBeanDefinition BeanDefinition
的直接实现,从中也可以看到一些特性的默认值
scope
默认为单例
延迟加载默认关闭
自动注入默认关闭
角色默认为ROLE_APPLICATION
RootBeanDefinition 说实话直接看这个类时,有点懵,原注释这么说。
A root bean definition represents the merged bean definition that backs a specific bean in a Spring BeanFactory at runtime. It might have been created from multiple original bean definitions that inherit from each other, typically registered as GenericBeanDefinitions. A root bean definition is essentially the ‘unified’ bean definition view at runtime. Root bean definitions may also be used for registering individual bean definitions in the configuration phase. However, since Spring 2.5, the preferred way to register bean definitions programmatically is the GenericBeanDefinition class. GenericBeanDefinition has the advantage that it allows to dynamically define parent dependencies, not ‘hard-coding’ the role as a root bean definition.
我看懂了字面意思,却没看懂这串英文背后的含义。什么是MergedBean
,关于这点,可以参考这篇文章 ,所谓合并,就是将具有父子关系的BeanDefinition
合并为一个BeanDefinition
。”合并“的具体过程,下文”如何创建Bean“将会分析。
GenericBeanDefinition BeanDefinition
的标准实现,相较于AbstractBeanDefinition
,它多了对父子关系的实现。我们是可以直接用该类创建自己的BeanDefinition
的。如果我们要凭空创建一个BeanDefinition
注入容器,可以用它。
AnnotatedBeanDefinition BeanDefinition
的直接扩展接口,向调用者暴露了AnnotationMetadata
。那么问题来了,什么是AnnotationMetadata
呢?它是Spring为指定类的注解所定义的抽象,通过它可以不加载目标类即可获取到注解信息。类似的还有ClassMetadata
。看来,Spring是将Bean定义的方方面面都进行了抽象。
AnnotatedGenericBeanDefinition 同时实现了GenericBeanDefinition
和AnnotatedBeanDefinition
,表明它既具有一个完整BeanDefinition
的能力,又持有Bean原类上的注解信息。持有注解信息有什么用呢?当然有用,运行时可以直接获取Bean定义的注解而不加载原类呀,提升性能。
ScannedGenericBeanDefinition 和AnnotatedGenericBeanDefinition
一样,可以说是一模一样。
小结 Spring关于Bean的描述,其实不止这几个类,但我认为其它都是干扰,因此去掉了。我们的重点,是要通过这些定义看到Spring是如何进行抽象的,以及各级抽象的作用。写代码时不会用到,但它可保看源码时不会懵逼。
Bean定义从何而来 还是上一篇文章那个例子,一个最最简单的应用方式。
1 2 3 4 fun main () { val context = AnnotationConfigApplicationContext("com.gitee.floyd.springme.core" ) println(context.getBean(Bean1::class .java )) }
我们以org.springframework.context.annotation.AnnotationConfigApplicationContext
构造方法为入口,分析Bean定义加载的过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public AnnotationConfigApplicationContext (String... basePackages) { this (); scan(basePackages); ... ... } public AnnotationConfigApplicationContext () { this .reader = new AnnotatedBeanDefinitionReader(this ); this .scanner = new ClassPathBeanDefinitionScanner(this ); } public void scan (String... basePackages) { ... ... this .scanner.scan(basePackages); ... ... }
这里引入两个新的类:AnnotatedBeanDefinitionReader
和ClassPathBeanDefinitionScanner
,我们先看它们的能力,再看这个扫描的过程
AnnotatedBeanDefinitionReader 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 public class AnnotatedBeanDefinitionReader { private final BeanDefinitionRegistry registry; private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE; private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver(); private ConditionEvaluator conditionEvaluator; ... ... public void registerBean (Class<?> beanClass) { doRegisterBean(beanClass, null , null , null , null ); } ... ... private <T> void doRegisterBean (Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); if (this .conditionEvaluator.shouldSkip(abd.getMetadata())) { return ; } abd.setInstanceSupplier(supplier); ScopeMetadata scopeMetadata = this .scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); String beanName = (name != null ? name : this .beanNameGenerator.generateBeanName(abd, this .registry)); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null ) { for (Class<? extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true ); } else if (Lazy.class == qualifier) { abd.setLazyInit(true ); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } if (customizers != null ) { for (BeanDefinitionCustomizer customizer : customizers) { customizer.customize(abd); } } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this .registry); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this .registry); } } static void processCommonDefinitionAnnotations (AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); if (lazy != null ) { abd.setLazyInit(lazy.getBoolean("value" )); } else if (abd.getMetadata() != metadata) { lazy = attributesFor(abd.getMetadata(), Lazy.class); if (lazy != null ) { abd.setLazyInit(lazy.getBoolean("value" )); } } if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true ); } AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); if (dependsOn != null ) { abd.setDependsOn(dependsOn.getStringArray("value" )); } AnnotationAttributes role = attributesFor(metadata, Role.class); if (role != null ) { abd.setRole(role.getNumber("value" ).intValue()); } AnnotationAttributes description = attributesFor(metadata, Description.class); if (description != null ) { abd.setDescription(description.getString("value" )); } }
要点总结
AnnotatedBeanDefinitionReader
,封装了BeanDefinition
构建并注入BeanDefinitionRegistry
的流程,这里BeanDefinitionRegistry
就是我们的容器
BeanDefinitionRegistry
,在前面介绍ApplicationContext
就已经介绍过,用于接收并持有Bean定义
bean名称生成器:AnnotationBeanNameGenerator
,按照@Component
及其子注解、@ManagedBean
、@Named
生成,详细分析见下
Scope
元信息,包含了Scope
的作用范围、代理模式,通过@Scope
注解标识,AnnotationScopeMetadataResolver
就是解析@Scope
注解的。如果未指定@Scope
注解,得到的结果是:单例+不代理。
ConditionEvaluator
,条件解析器。针对@Conditional
进行解析。详细分析见下文。
bean名称生成逻辑 AnnotationBeanNameGenerator这个类值得看一看,它有一些隐藏的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component" ; @Override public String generateBeanName (BeanDefinition definition, BeanDefinitionRegistry registry) { if (definition instanceof AnnotatedBeanDefinition) { String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition); if (StringUtils.hasText(beanName)) { return beanName; } } return buildDefaultBeanName(definition, registry); } protected String determineBeanNameFromAnnotation (AnnotatedBeanDefinition annotatedDef) { AnnotationMetadata amd = annotatedDef.getMetadata(); Set<String> types = amd.getAnnotationTypes(); String beanName = null ; for (String type : types) { AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type); if (attributes != null ) { Set<String> metaTypes = this .metaAnnotationTypesCache.computeIfAbsent(type, key -> { Set<String> result = amd.getMetaAnnotationTypes(key); return (result.isEmpty() ? Collections.emptySet() : result); }); if (isStereotypeWithNameValue(type, metaTypes, attributes)) { Object value = attributes.get("value" ); if (value instanceof String) { String strVal = (String) value; if (StringUtils.hasLength(strVal)) { if (beanName != null && !strVal.equals(beanName)) { throw new IllegalStateException("Stereotype annotations suggest inconsistent " + "component names: '" + beanName + "' versus '" + strVal + "'" ); } beanName = strVal; } } } } } return beanName; } protected boolean isStereotypeWithNameValue (String annotationType, Set<String> metaAnnotationTypes, @Nullable Map<String, Object> attributes) { boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) || metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) || annotationType.equals("javax.annotation.ManagedBean" ) || annotationType.equals("javax.inject.Named" ); return (isStereotype && attributes != null && attributes.containsKey("value" )); } protected String buildDefaultBeanName (BeanDefinition definition) { String beanClassName = definition.getBeanClassName(); Assert.state(beanClassName != null , "No bean class name set" ); String shortClassName = ClassUtils.getShortName(beanClassName); return Introspector.decapitalize(shortClassName); } }
要点
支持生成Bean名称的注解有:@Component
及其子注解、@MangedBean
、@Named
如果这些注解没有显式指明名称,则回退成默认规则:类名首字母小写
判定BeanDefinition是否需要被加载 ConditionEvaluator这个类也值得一看,它解释了@Conditional
注解的工作原理。整个类就暴露一个方法:shouldSkip()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public boolean shouldSkip (@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) { if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { return false ; } if (phase == null ) { if (metadata instanceof AnnotationMetadata && ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) { return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION); } return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN); } List<Condition> conditions = new ArrayList<>(); for (String[] conditionClasses : getConditionClasses(metadata)) { for (String conditionClass : conditionClasses) { Condition condition = getCondition(conditionClass, this .context.getClassLoader()); conditions.add(condition); } } AnnotationAwareOrderComparator.sort(conditions); for (Condition condition : conditions) { ConfigurationPhase requiredPhase = null ; if (condition instanceof ConfigurationCondition) { requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase(); } if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this .context, metadata)) { return true ; } } return false ; }
分析一下ConfigurationClassUtils.isConfigurationCandidate()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 private static final Set<String> candidateIndicators = new HashSet<>(8 );static { candidateIndicators.add(Component.class.getName()); candidateIndicators.add(ComponentScan.class.getName()); candidateIndicators.add(Import.class.getName()); candidateIndicators.add(ImportResource.class.getName()); } public static boolean isConfigurationCandidate (AnnotationMetadata metadata) { if (metadata.isInterface()) { return false ; } for (String indicator : candidateIndicators) { if (metadata.isAnnotated(indicator)) { return true ; } } return hasBeanMethods(metadata); } static boolean hasBeanMethods (AnnotationMetadata metadata) { try { return metadata.hasAnnotatedMethods(Bean.class.getName()); } catch (Throwable ex) { ... ... } }
理解关键
AnnotatedTypeMetadata
要理解,前面AnnotatedBeanDefinition
看到过,Spring将Bean
上的注解信息和类信息进行了抽象,使得不需要加载具体的类就能获取其上的注解,使用方便。
Condition
条件,它只有一个匹配方法boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
,用于匹配指定Bean在容器中是否满足条件,我们常用的@ConditionalOnClassMissingBean
之类的注解,就是@Conditional
派生注解+Condition
派生类组合完成的。
要点总结
ConditionEvaluator
是用来判断某个Bean定义是否符合加载条件,是加载还是有应该被忽略。判断逻辑
如果不存在@Conditional
注解,则需要加载
如果存在@Conditional
注解,则需要看该注解的作用阶段和其内部Condition
的行为
如果Condition
所指定的阶段与@Conditional
实际作用的阶段不一致,则需要加载
否则,根据Condition.matches()
的结果来判定是否需要加载
当一个Bean定义被@Component、@ComponentScan、@Import、@ImportResource
注解,或其内含有@Bean
注解方法时,说明它是一个配置Bean。即作用阶段是ConfigurationPhase.PARSE_CONFIGURATION
,否则,作用阶段是ConfigurationPhase.REGISTER_BEAN
,作用阶段,也可以用来判断是否需要加载该Bean定义:当声明的作用阶段和Condition
类的作用阶段不一致时,将忽略匹配过程,直接加载
ClassPathBeanDefinitionScanner
继承树如上
ClassPathScanningCandidateComponentProvider
用于在指定包下扫描并提供Bean定义(所谓的CandidateComponent
),核心逻辑在public Set<BeanDefinition> findCandidateComponents(String basePackage)
方法。
ClassPathBeanDefinitionScanner
用于批量扫描包下的Bean定义,核心逻辑在protected Set<BeanDefinitionHolder> doScan(String... basePackages)
方法。
我们按照调用关系来看,从scan方法看起
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 public int scan (String... basePackages) { doScan(basePackages); if (this .includeAnnotationConfig) { AnnotationConfigUtils.registerAnnotationConfigProcessors(this .registry); } return ... } protected Set<BeanDefinitionHolder> doScan (String... basePackages) { Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); for (String basePackage : basePackages) { Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { ScopeMetadata scopeMetadata = this .scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this .beanNameGenerator.generateBeanName(candidate, this .registry); if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this .registry); beanDefinitions.add(definitionHolder); registerBeanDefinition(definitionHolder, this .registry); } } } return beanDefinitions; } protected void postProcessBeanDefinition (AbstractBeanDefinition beanDefinition, String beanName) { beanDefinition.applyDefaults(this .beanDefinitionDefaults); if (this .autowireCandidatePatterns != null ) { beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this .autowireCandidatePatterns, beanName)); } } public void applyDefaults (BeanDefinitionDefaults defaults) { Boolean lazyInit = defaults.getLazyInit(); if (lazyInit != null ) { setLazyInit(lazyInit); } setAutowireMode(defaults.getAutowireMode()); setDependencyCheck(defaults.getDependencyCheck()); setInitMethodName(defaults.getInitMethodName()); setEnforceInitMethod(false ); setDestroyMethodName(defaults.getDestroyMethodName()); setEnforceDestroyMethod(false ); }
上面有调用到ClassPathScanningCandidateComponentProvider
的findCandidateComponents
方法,我们再看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public Set<BeanDefinition> findCandidateComponents (String basePackage) { if (this .componentsIndex != null && indexSupportsIncludeFilters()) { return addCandidateComponentsFromIndex(this .componentsIndex, basePackage); } else { return scanCandidateComponents(basePackage); } } private Set<BeanDefinition> scanCandidateComponents (String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); try { String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this .resourcePattern; Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath); for (Resource resource : resources) if (resource.isReadable()) { try { MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setSource(resource); if (isCandidateComponent(sbd)) { candidates.add(sbd); } } } catch (Throwable ex) { throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex); } } } } catch (IOException ex) { throw new BeanDefinitionStoreException("I/O failure during classpath scanning" , ex); } return candidates; } protected boolean isCandidateComponent (MetadataReader metadataReader) throws IOException { for (TypeFilter tf : this .excludeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return false ; } } for (TypeFilter tf : this .includeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return isConditionMatch(metadataReader); } } return false ; }
上面只贴出了直接从类中扫描的代码,但另一个addCandidateComponentsFromIndex
没说。我们需要先知道一下Spring中的Index是什么。可以参考这篇文章 :
在项目中使用了@Indexed
之后,编译打包的时候会在项目中自动生成META-INT/spring.components
文件。 当Spring应用上下文执行ComponentScan
扫描时,META-INT/spring.components
将会被CandidateComponentsIndexLoader
读取并加载,转换为CandidateComponentsIndex
对象,这样的话@ComponentScan
不在扫描指定的package,而是读取CandidateComponentsIndex
对象,从而达到提升性能的目的。
此时我们再去跟踪addCandidateComponentsFromIndex()
方法,会发现和上面说的可以说是一模一样了。
要点总结
可以看到,ClassPathBeanDefinitionScanner
做的事和AnnotatedBeanDefinitionReader
差不多,都是构建BeanDefinition
并向容器中注册;唯一的差别是,前者的Bean定义是自己扫描得来的,而后者的Bean定义是外界调用方法注册来的
通过ClassPathScanningCandidateComponentProvider.findCandidateComponents()
我们知道,它只提供最原始的扫描并生成BeanDefinition
的逻辑,而BeanDefinition
各种属性的解析和设置放在其子类ClassPathBeanDefinitionScanner
中了。
小结 这一个Reader,一个Scanner,都只是一个工具,最终完成了容器中的BeanDefinition
创建。
如何创建Bean Bean的创建逻辑 Bean的创建有几个时机
对于非延迟加载的单例Bean,在容器refresh时就会被创建,在ApplicationContext
源码分析时我们看到过
对于延迟加载的单例Bean,在第一次被获取时会被创建
对于原型Bean,每次被获取时都会被创建
我们先看第一种情况,直接进org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
,我删掉了不重要的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 public void preInstantiateSingletons () throws BeansException { List<String> beanNames = new ArrayList<>(this .beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); if (isEagerInit) { getBean(beanName); } } } else { getBean(beanName); } } } for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; smartSingleton.afterSingletonsInstantiated(); } } } public Object getBean (String name) throws BeansException { return doGetBean(name, null , null , false ); } protected <T> T doGetBean (String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) { String beanName = transformedBeanName(name); Object beanInstance; Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null ) { beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null ); } else { BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null ) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null ) { return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null ) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'" ); } try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'" , ex); } } } if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { Object prototypeInstance = null ; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); Scope scope = this .scopes.get(scopeName); try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } return adaptBeanInstance(name, beanInstance, requiredType); } <T> T adaptBeanInstance (String name, Object bean, @Nullable Class<?> requiredType) { if (requiredType != null && !requiredType.isInstance(bean)) { try { Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null ) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return (T) convertedBean; } catch (TypeMismatchException ex) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
上面虽然只是预加载单例Bean的代码,但方法doGetBean()
却是获取Bean的通用方法,对此,可以有所总结:
单例Bean的创建, 先从缓存中获取;如果没有,再从父容器中获取,如果再没有,则执行创建逻辑
如果一个Bean有依赖的Bean,则该依赖Bean将会首先被创建;如果被依赖的Bean又依赖了原Bean,则构成循环依赖,Spring将会抛出异常
scope的实现只有三种情况
单例:当BeanDefinition
的scope没有值(即默认单例)或为singleton
时,为单例,整个容器只维护一份实例
原型:当BeanDefinition
的scope为prototye
时,为原型,每次都会执行一遍新建Bean的逻辑
其它:当BeanDefinition
的scope非上述任何一种时,为其它,实现方式是容器维护一个名为scopes
的Map,每个entry的值为Scope
对象,它就是一个容器,新建的Bean会放入该容器。构成对同一个Scope
只存在一份Bean。
创建完成的Bean实例,并不能直接使用:如果有指定预期的类型,还要调用容器内维护的类型转换器进行一次类型转换,得到最终值
对于正常情况下的Bean获取方法如org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String)
,有如下
1 2 3 4 5 6 7 8 9 public Object getBean (String name) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name); } public Object getBean (String name) throws BeansException { return doGetBean(name, null , null , false ); }
可以看到它又是调用了doGetBean(),还是那个通用方法,这里略过不记。
MergedBeanDefinition 先说明,没有这个类或接口定义,但是前文”如何描述Bean“提到了合并Bean定义的概念,”Bean的创建逻辑“又再次看到了这个概念,它到底什么意思?我们从org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
方法来看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 protected RootBeanDefinition getMergedLocalBeanDefinition (String beanName) throws BeansException { RootBeanDefinition mbd = this .mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } protected RootBeanDefinition getMergedBeanDefinition (String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { return getMergedBeanDefinition(beanName, bd, null ); } protected RootBeanDefinition getMergedBeanDefinition (String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException { synchronized (this .mergedBeanDefinitions) { RootBeanDefinition mbd = null ; RootBeanDefinition previous = null ; if (containingBd == null ) { mbd = this .mergedBeanDefinitions.get(beanName); } if (mbd == null || mbd.stale) { previous = mbd; if (bd.getParentName() == null ) { if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } else { BeanDefinition pbd; try { String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { pbd = getMergedBeanDefinition(parentBeanName); } else { BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'" , ex); } mbd = new RootBeanDefinition(pbd); mbd.overrideFrom(bd); } if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(SCOPE_SINGLETON); } if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } if (containingBd == null && isCacheBeanMetadata()) { this .mergedBeanDefinitions.put(beanName, mbd); } } if (previous != null ) { copyRelevantMergedBeanDefinitionCaches(previous, mbd); } return mbd; } } private void copyRelevantMergedBeanDefinitionCaches (RootBeanDefinition previous, RootBeanDefinition mbd) { if (ObjectUtils.nullSafeEquals(mbd.getBeanClassName(), previous.getBeanClassName()) && ObjectUtils.nullSafeEquals(mbd.getFactoryBeanName(), previous.getFactoryBeanName()) && ObjectUtils.nullSafeEquals(mbd.getFactoryMethodName(), previous.getFactoryMethodName())) { ResolvableType targetType = mbd.targetType; ResolvableType previousTargetType = previous.targetType; if (targetType == null || targetType.equals(previousTargetType)) { mbd.targetType = previousTargetType; mbd.isFactoryBean = previous.isFactoryBean; mbd.resolvedTargetType = previous.resolvedTargetType; mbd.factoryMethodReturnType = previous.factoryMethodReturnType; mbd.factoryMethodToIntrospect = previous.factoryMethodToIntrospect; } } }
关键是父Bean定义被子Bean定义覆盖,看org.springframework.beans.factory.support.AbstractBeanDefinition#overrideFrom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public void overrideFrom (BeanDefinition other) { if (StringUtils.hasLength(other.getBeanClassName())) { setBeanClassName(other.getBeanClassName()); } if (StringUtils.hasLength(other.getScope())) { setScope(other.getScope()); } setAbstract(other.isAbstract()); if (StringUtils.hasLength(other.getFactoryBeanName())) { setFactoryBeanName(other.getFactoryBeanName()); } if (StringUtils.hasLength(other.getFactoryMethodName())) { setFactoryMethodName(other.getFactoryMethodName()); } setRole(other.getRole()); setSource(other.getSource()); copyAttributesFrom(other); if (other instanceof AbstractBeanDefinition) { AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other; if (otherAbd.hasBeanClass()) { setBeanClass(otherAbd.getBeanClass()); } if (otherAbd.hasConstructorArgumentValues()) { getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues()); } if (otherAbd.hasPropertyValues()) { getPropertyValues().addPropertyValues(other.getPropertyValues()); } if (otherAbd.hasMethodOverrides()) { getMethodOverrides().addOverrides(otherAbd.getMethodOverrides()); } Boolean lazyInit = otherAbd.getLazyInit(); if (lazyInit != null ) { setLazyInit(lazyInit); } setAutowireMode(otherAbd.getAutowireMode()); setDependencyCheck(otherAbd.getDependencyCheck()); setDependsOn(otherAbd.getDependsOn()); setAutowireCandidate(otherAbd.isAutowireCandidate()); setPrimary(otherAbd.isPrimary()); copyQualifiersFrom(otherAbd); setInstanceSupplier(otherAbd.getInstanceSupplier()); setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(otherAbd.isLenientConstructorResolution()); if (otherAbd.getInitMethodName() != null ) { setInitMethodName(otherAbd.getInitMethodName()); setEnforceInitMethod(otherAbd.isEnforceInitMethod()); } if (otherAbd.getDestroyMethodName() != null ) { setDestroyMethodName(otherAbd.getDestroyMethodName()); setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod()); } setSynthetic(otherAbd.isSynthetic()); setResource(otherAbd.getResource()); } else { getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues()); getPropertyValues().addPropertyValues(other.getPropertyValues()); setLazyInit(other.isLazyInit()); setResourceDescription(other.getResourceDescription()); } }
要点总结:所谓合并,就是有父子关系的BeanDefinition
的合并,将他们合并为一个BeanDefinition
,合并逻辑是:用子BeanDefinition
覆盖父BeanDefinition
,最终结果用RootBeanDefinition
表示。
自动注入
自动注入这块的代码实在太多,这里分成几个部分分别来说
到现在为止,我们还没看到自动注入,BeanPostProcessor
等的执行逻辑,它们都在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
中,前文创建Bean的源码有调用它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 protected Object createBean (String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null ) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } mbdToUse.prepareMethodOverrides(); Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null ) { return bean; } Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; }
这里唯一需要注意的点:可以通过InstantiationAwareBeanPostProcessor
提供一个代理实例,这为Spy之类的测试功能提供了方便,使得他们可以伪造bean,构建测试环境。
创建实例前的操作 对resolveBeforeInstantiation
,有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 protected Object resolveBeforeInstantiation (String beanName, RootBeanDefinition mbd) { Object bean = null ; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null ) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null ) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null ); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation (Class<?> beanClass, String beanName) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null ) { return result; } } return null ; } public Object applyBeanPostProcessorsAfterInitialization (Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null ) { return result; } result = current; } return result; }
创建实例操作总览 对创建的实际操作,有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 protected Object doCreateBean (String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null ; if (mbd.isSingleton()) { instanceWrapper = this .factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null ) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true ; } } boolean earlySingletonExposure = (mbd.isSingleton() && this .allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false ); if (earlySingletonReference != null ) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this .allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw ... ... } } } } registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; }
注意点1:创建Bean的步骤:创建、执行注入、执行初始化操作
注意点2:循环引用的解决方式
循环引用的解决方式 需要注意的是,这里有两种循环引用的方式
Scope
为单例时,则如”创建实例操作总览“中的代码那样,确切来说,应该这么梳理
首先,Spring维护三个有关单例缓存
singletonObjects
:用于维护已经创建好的单例对象
earlySingletonObjects
:用于维护创建了但尚未执行自动注入和初始化的单例对象
singletonFactories
:用于维护单例对象产生的工厂实例
然后来看注入的具体方法,比如按照name注入,它还是调用了getBean
方法获取Bean,其中会调用getSingleton
方法获取实例对象
先从singletonObjects
中获取已经创建好的单例对象
再尝试从earlySingletonObjects
中获取创建到一般的单例对象
再尝试用对应的singletonFactories
创建出一个单例对象,注意该对象会加入earlySingletonObjects
,所以其实为了理解方便,singletonFactories
您可以暂时忽略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected Object getSingleton (String beanName, boolean allowEarlyReference) { singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null ) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null ) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } return singletonObject; }
然后再看创建Bean时干了什么(截取前文的代码):增加了一个singletonFactory
,结合前面的分析,其实就是把刚创建但还没有注入属性和初始化的bean放在了earlySingletonObjects
中,使得如果有循环依赖时能够直接获取到该bean。避免死循环。
1 2 3 4 if (earlySingletonExposure) { addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
总结来说,这里的重点是将bean的创建和初始化(包括注入)分开进行,保有一个半初始化的状态,使得能够注入半初始化状态的Bean。
但是,这是setter注入时才可以这么做,构造器注入又当如何呢? 事实上,因为构造器注入时,当前对象尚未创建完成,没法有一个半初始化状态,因此构造器注入不允许循环依赖。
Scope
为原型时,参考AbstractBeanFactory.doCreate.273行
,这里有检查当前线程下同名的原型Bean是否正在创建。Spring是一个同步框架,在创建原型Bean时,同一个线程不可能同时创建两个原型Bean,那么很明显了,就如注释所说,这里是不允许原型Bean循环引用。
1 2 3 4 5 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }
为什么原型时不支持循环依赖?因为Spring不会缓存任何有关原型的状态,虽然它也能有中间状态,但Spring并不缓存它,这是一个技术上可以实现,但Spring的设计思想上不允许存在的场景:所谓原型,每次获取Bean都要创建一个新的,那么当循环依赖时,应该获得的是一个与”我“完全不同的Bean。
BeanWrapper是什么 该类不是给我们直接使用的,而是在容器内部流通。用于提供实际Bean实例的分析和操作,如针对属性的操作、查询等。它常用的只有一个实现类BeanWrapperImpl
。了解它有助于源码的查看,这里我们简要看一下接口定义
1 2 3 4 5 6 7 8 9 10 public interface BeanWrapper extends ConfigurablePropertyAccessor { Object getWrappedInstance () ; Class<?> getWrappedClass(); PropertyDescriptor[] getPropertyDescriptors(); PropertyDescriptor getPropertyDescriptor (String propertyName) throws InvalidPropertyException ; }
创建实例的确切操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName); Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null ) { return obtainFromSupplier(instanceSupplier, beanName); } if (mbd.getFactoryMethodName() != null ) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false ; boolean autowireNecessary = false ; if (args == null ) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null ) { resolved = true ; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null , null ); } else { return instantiateBean(beanName, mbd); } } Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } ctors = mbd.getPreferredConstructors(); if (ctors != null ) { return autowireConstructor(beanName, mbd, ctors, null ); } return instantiateBean(beanName, mbd); }
创建备选方式的顺序
提前设置的Supplier
指定的工厂方法
使用BeanDefinition
提前解析好的构造器创建
使用SmartInstantiationAwareBeanPostProcessor
提供的构造器创建
使用类自带的有参构造器创建,参数来自容器,自动注入
使用类自带的无参构造器创建
按有参构造器注入并创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 public BeanWrapper autowireConstructor (String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this .beanFactory.initBeanWrapper(bw); Constructor<?> constructorToUse = null ; ArgumentsHolder argsHolderToUse = null ; Object[] argsToUse = null ; if (explicitArgs != null ) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null ; synchronized (mbd.constructorArgumentLock) { constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null ) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null ) { argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve); } } if (constructorToUse == null || argsToUse == null ) { Constructor<?>[] candidates = chosenCtors; if (candidates == null ) { Class<?> beanClass = mbd.getBeanClass(); candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors()); } if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) { Constructor<?> uniqueCandidate = candidates[0 ]; if (uniqueCandidate.getParameterCount() == 0 ) { synchronized (mbd.constructorArgumentLock) { mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate; mbd.constructorArgumentsResolved = true ; mbd.resolvedConstructorArguments = EMPTY_ARGS; } bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS)); return bw; } } boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null ; int minNrOfArgs; if (explicitArgs != null ) { minNrOfArgs = explicitArgs.length; } else { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } AutowireUtils.sortConstructors(candidates); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Constructor<?>> ambiguousConstructors = null ; Deque<UnsatisfiedDependencyException> causes = null ; for (Constructor<?> candidate : candidates) { int parameterCount = candidate.getParameterCount(); ArgumentsHolder argsHolder; Class<?>[] paramTypes = candidate.getParameterTypes(); if (resolvedValues != null ) { String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount); if (paramNames == null ) { ParameterNameDiscoverer pnd = this .beanFactory.getParameterNameDiscoverer(); if (pnd != null ) { paramNames = pnd.getParameterNames(candidate); } } argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1 ); } else { if (parameterCount != explicitArgs.length) { continue ; } argsHolder = new ArgumentsHolder(explicitArgs); } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousConstructors = null ; } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { if (ambiguousConstructors == null ) { ambiguousConstructors = new LinkedHashSet<>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } } if (constructorToUse == null ) { throw new BeanCreationException(......); } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) { throw new BeanCreationException(......); } } Assert.state(argsToUse != null , "Unresolved constructor arguments" ); bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); return bw; }
Spring会先从容器中找出满足类型要求的参数组合,然后找出与这些参数类型最为匹配的构造器,用以创建实例
可以想见,只要有精确类型的bean被创建,就一定能够实例化成功,因为不可能有完全一样参数类型的构造器嘛
使用无参构造器创建 1 2 3 4 5 6 7 8 protected BeanWrapper instantiateBean (String beanName, RootBeanDefinition mbd) { Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this ); BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; }
自动注入逻辑的执行 对自动注入的逻辑,即populateBean()
,有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 protected void populateBean (String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return ; } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null ); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null ; if (hasInstAwareBpps) { if (pvs == null ) { pvs = mbd.getPropertyValues(); } for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null ) { if (filteredPds == null ) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null ) { return ; } } pvs = pvsToUse; } } if (needsDepCheck) { if (filteredPds == null ) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null ) { applyPropertyValues(beanName, mbd, bw, pvs); } } protected void autowireByName (String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { Object bean = getBean(propertyName); pvs.add(propertyName, bean); registerDependentBean(propertyName, beanName); } } } protected void autowireByType (String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null ) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4 ); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null ) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { registerDependentBean(autowiredBeanName, beanName); } autowiredBeanNames.clear(); } } }
实例初始化的操作 对初始化的逻辑有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 protected Object initializeBean (String beanName, Object bean, @Nullable RootBeanDefinition mbd) { invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } invokeInitMethods(beanName, wrappedBean, mbd); if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
实例化包含内容
BeanxxxAware
接口的调用
BeanPostProcessor.postProcessBeforeInitialization
的调用
InitializingBean.afterPropertiesSet
的调用
自定义初始化方法的调用
BeanPostProcessor.postProcessAfterInitialization
的调用
根据依赖类型得到依赖实例的操作 在执行自动注入逻辑时,有用到如下方法,我们一起来看看它干了什么:org.springframework.beans.factory.config.AutowireCapableBeanFactory#resolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set<java.lang.String>, org.springframework.beans.TypeConverter)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 javaxInjectProviderClass = ClassUtils.forName("javax.inject.Provider" , DefaultListableBeanFactory.class.getClassLoader()); public Object resolveDependency (DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName); if (result == null ) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } } public Object doResolveDependency (DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { Class<?> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null ) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null ); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null ) { return multipleBeans; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null ; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1 ) { autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null ) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); } else { return null ; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null ) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this ); } Object result = instanceCandidate; return result; } protected Map<String, Object> findAutowireCandidates (@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this , requiredType, true , descriptor.isEager()); Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length); for (Map.Entry<Class<?>, Object> classObjectEntry : this .resolvableDependencies.entrySet()) { Class<?> autowiringType = classObjectEntry.getKey(); if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = classObjectEntry.getValue(); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break ; } } } for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } ... ... return result; } private void addCandidateEntry (Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) { if (descriptor instanceof MultiElementDescriptor) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this ); if (!(beanInstance instanceof NullBean)) { candidates.put(candidateName, beanInstance); } } else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor && ((StreamDependencyDescriptor) descriptor).isOrdered())) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this ); candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } else { candidates.put(candidateName, getType(candidateName)); } }
小结 Bean的创建,可说是重中之重,因为它关系到Spring的生命周期,这是面试中超高频率被问到的问题。有了上面的分析,我们可以自己总结一波创建过程会经过哪些关键过程,这其实有两种case
case1
首先执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
提供一个创建代理的机会,如果代理创建成功
执行所有的BeanPostProcessor.postProcessAfterInitialization()
方法
对于预加载的单例Bean,还会调用SmartInitializingSingleton.afterSingletonsInstantiated()
结束
case2
实例化Bean
尝试使用指定的工厂方法创建
尝试使用构造方法创建,如果使用有参构造方法,构造方法的参数会被自动注入
应用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
对需要的属性进行自动注入,按名称或类型从容器中寻找符合要求的Bean,注入
调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
应用BeanPostProcessor.postProcessBeforeInitialization()
应用InitializingBean.afterPropertiesSet()
应用自定义init方法
应用BeanPostProcessor.postProcessAfterInitialization
对于预加载的单例Bean,还会调用SmartInitializingSingleton.afterSingletonsInstantiated()
结束
注意这里讨论的是Spring中Bean的生命周期,而不是Spring的生命周期,如果是后者,请翻看第一篇文章分析。
如何销毁Bean JVM中的对象,通过可达性分析,垃圾回收机制,进行回收;Spring中的Bean对象,总是被容器持有,岂不是永远不可能被垃圾回收?这个想法是正确的,这种设计也是合理的。但要注意到有一个前提:Scope
,正因为有它的存在,Bean的生命周期管理才变得方便。
对于Scope
为单例的Bean,容器全局唯一,被容器引用,当然不会也不能被销毁
对于Scope
为原型的Bean,创建完成后容器内部并没有引用,交给应用程序,这和普通new出来的对象一致,是能够被回收的
对于Scope
为其它的Bean,则看Scope
而定,Scope
销毁,Bean对象一并被回收,这种情况没见过;要不然就交给Scope
自己处理了,这倒是见过,比如web里面的Request或Session范围的Scope,它是将Bean对象保存在HttpServletRequest
或HttpSession
中,即生命周期随请求或Session的销毁而结束。
我们关注两个点:随容器一起销毁的Bean如何销毁;生命周期不跟随容器的Bean如何销毁
被容器销毁 容器的销毁方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 protected void doClose () { if (this .active.get() && this .closed.compareAndSet(false , true )) { publishEvent(new ContextClosedEvent(this )); if (this .lifecycleProcessor != null ) { this .lifecycleProcessor.onClose(); } destroyBeans(); closeBeanFactory(); onClose(); this .active.set(false ); } } protected void destroyBeans () { getBeanFactory().destroySingletons(); } public void destroySingletons () { String[] disposableBeanNames; synchronized (this .disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this .disposableBeans.keySet()); } for (int i = disposableBeanNames.length - 1 ; i >= 0 ; i--) { destroySingleton(disposableBeanNames[i]); } } public void destroySingleton (String beanName) { ... ... destroyBean(beanName, disposableBean); } protected void destroyBean (String beanName, @Nullable DisposableBean bean) { ... ... bean.destroy(); ... ... }
可以看到,容器关闭时,只销毁了单例Bean,调用了两个有关生命周期的方法
LifyCycle.close()
DisposableBean.destroy()
但还有一种Bean的销毁回调没有被我们看到:自定义销毁方法的调用
被JVM销毁 正如注解方法org.springframework.context.annotation.Bean#destroyMethod
上的注释而言,只有生命周期被容器完全控制的Bean才能正常被容器调用各种销毁方法,也就是单例,其它Scope
都无法保证。因此类似原型、上面说的Session之类的生命周期方法,都是不能被正常调用的,因为容器管不了他们呀。
Note: Only invoked on beans whose lifecycle is under the full control of the factory, which is always the case for singletons but not guaranteed for any other scope.
总结 这文章写了三天你能信???
总结一下,本文从源码的角度,介绍了Spring如何描述Bean,如何在容器创建时扫描Bean,在不同的时机如何创建Bean,Bean的循环依赖的解决方式,自动注入的逻辑,不同Scope
的Bean的销毁场景等问题。但已就算是走马观花,不过今后遇到问题时应该很快能够定位问题吧🤔。
命名规则
xxxxProvider:Provider算是策略模式+抽象工厂模式的结合。所谓抽象工厂模式,意味着它封装了创建实例的过程;所谓策略模式,意味着它可以被当做策略传入其它以他为基础的类中。比如ClassPathScanningCandidateComponentProvider
之于AnnotationConfigApplicationContext
。
下一篇写什么 Spring源码剖析 - 强大的BeanPostProcessor